/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
/**
 * Software License, Version 1.0
 *
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 *
 *
 *Redistribution and use in source and binary forms, with or without
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For
 * further information contact the Community Grids Lab at
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and
 * wherever such third-party acknowledgments normally appear.
 *
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering,
 * shall not be used to endorse or promote products derived from this software
 * without prior written permission from Indiana University.  For written
 * permission, please contact the Advanced Research and Technology Institute
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering,
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 *
 *
 * Indiana University provides no reassurances that the source code provided
 * does not infringe the patent or any other intellectual property rights of
 * any other entity.  Indiana University disclaims any liability to any
 * recipient for claims brought by any other entity based on infringement of
 * intellectual property rights or otherwise.
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS.
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS",
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.samples.nbNative;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Properties;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import cgl.narada.event.NBEvent;
import cgl.narada.event.TemplateInfo;
import cgl.narada.event.TemplateProfileAndSynopsisTypes;
import cgl.narada.service.ServiceException;
import cgl.narada.service.client.ClientService;
import cgl.narada.service.client.EventProducer;
import cgl.narada.service.client.NBEventListener;
import cgl.narada.service.client.NBRecoveryListener;
import cgl.narada.service.client.NBRecoveryNotification;
import cgl.narada.service.client.SessionService;
import cgl.narada.service.qos.ProducerConstraints;

/**
 * <p>Title: RobustPublisherGui </p>
 * <p>Description: Robust RobustPublisherGui </p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: Pervasive Tech Lab</p>
 * @author Beytullah Yildiz
 * @version 1.0
 */

public class RobustPublisherGui
    extends JPanel
    implements NBEventListener, NBRecoveryListener {
  JTextArea synopsisTextArea;
  JTextField templateTextField;

  int teplateId = 12345;
  String synopsis_name = "Movie/Casablanca";
  JButton createButton;
  //JButton recoverButton;
  JButton sendButton;
  private ClientService clientService;
  private String moduleName = "RobustPublisherGui: ";
  private EventProducer producer;
  private ProducerConstraints producerConstraints;

  int templateType_=1;

  /**
   * Constructor
   */
  public RobustPublisherGui() {

    super(new GridLayout(1, 1));

    int width = 400;
    int height = 300;

    JTabbedPane tabbedPane = new JTabbedPane();

    JComponent panel1 = makeConnectPanel();
    panel1.setPreferredSize(new Dimension(width, height));
    tabbedPane.addTab("Connect", panel1);
    tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);

    JComponent panel2 = makeTemplatePanel();
    panel2.setPreferredSize(new Dimension(width, height));
    tabbedPane.addTab("Template Info", panel2);
    tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);

    /*  JComponent panel3 = makeReceivePanel();
      panel3.setPreferredSize(new Dimension(width, height));
      tabbedPane.addTab("Receive", panel3);
      tabbedPane.setMnemonicAt(2, KeyEvent.VK_3);*/

    JComponent panel4 = makeSendPanel();
    panel4.setPreferredSize(new Dimension(width, height));
    tabbedPane.addTab("Send", panel4);
    tabbedPane.setMnemonicAt(2, KeyEvent.VK_3);

    //Add the tabbed pane to this panel.
    add(tabbedPane);
    // to use scrolling tabs.
    tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);

  }

  /**
   * initilize client service
   * @param entityId is client entity id
   */

  public void RobustPublisher(int entityId) {
    try {
      clientService = SessionService.getClientService(entityId);
      producer = clientService.createEventProducer();
    }
    catch (ServiceException serviceException) {
      System.out.println(serviceException);
    }
  }

  /**
   * Initilize broker communication
   * @param properties
   * @param string
   * @throws ServiceException
   */
  public void initializeBrokerCommunications
      (Properties properties, String string) throws ServiceException {
    clientService.initializeBrokerCommunications(properties, string);
    
  }

  /**
   * initilize producer
   * @param templateID is teplate id
   * @param synopsis for producer
   * @throws ServiceException
   */
  public void initializeProducerAndConsumer(int templateID, int templateType,
                                            String synopsis) throws
      ServiceException {
    TemplateInfo templateinfo = null;

    if (templateType == TemplateProfileAndSynopsisTypes.INTEGER) {
      Integer integerSynopsis = new Integer(Integer.parseInt(synopsis));
      templateinfo = clientService.createTemplateInfo(templateID, templateType,
						      integerSynopsis);
      
    } else {
      templateinfo = clientService.createTemplateInfo(templateID, templateType,
						      synopsis);
    }
    
    producerConstraints = producer.createProducerConstraints(templateinfo);
    producerConstraints.setSendReliably();
    long l = producer.recover(templateID, this);
    System.out.println(moduleName + 
		       "Assigned recovery id = [" + l + "] \n\n");
  }

  /**
   * publish events
   * @param string is message string
   * @param templateid is the template id
   * @param synopsis
   * @throws ServiceException
   */
  public void publishEvent(String string, int templateid, String synopsis) 
    throws ServiceException {
    if (string.equals("")) {
      string += System.currentTimeMillis();
    }
    producer.generateEventIdentifier(true);
    producer.setTemplateId(templateid);
    producer.setDisableTimestamp(false);
    NBEvent nbevent = null;

    if (templateType_ == TemplateProfileAndSynopsisTypes.INTEGER) {
      Object intObject = new Integer(Integer.parseInt(synopsis) );
      nbevent = producer.generateEvent(templateType_ , intObject, 
				       string.getBytes());
    } else {
      nbevent = 
	producer.generateEvent(templateType_ , synopsis, string.getBytes());
    }

    producer.publishEvent(nbevent, producerConstraints);
    System.out.println("following string is publishing " + string);
  }

  /**
   * listens the comming messages
   * @param nbevent is the comming message package
   */
  public void onEvent(NBEvent nbevent) {
    String st = new String(nbevent.getContentPayload());
    System.out.println("received message " + st);
    System.out.println(moduleName + "Received NBEvent " + nbevent);
  }

  /**
   * listens comming notification for recovery
   * @param nbrecoverynotification
   */
  public void onRecovery(NBRecoveryNotification nbrecoverynotification) {
    System.out.println(moduleName + nbrecoverynotification);
  }

  /**
   * create properties
   * @param hostname  host name
   * @param portnumber port number
   * @return properties
   */
  public Properties createProperties(String hostname, String portnumber) {
    Properties properties = new Properties();
    properties.put("hostname", hostname);
    properties.put("portnum", portnumber);
    return properties;
  }

  /**
   * Creates Connect Tabbed Pane
   * @return frame
   */

  protected JComponent makeConnectPanel() {
    //System.out.println("makeConnectPanel");
    JPanel panel = new JPanel(false);
    panel.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    JLabel entityLabel = new JLabel("Entity Id : ");
    final JTextField entityTextField = new JTextField("5555", 10);
    entityTextField.setEditable(false);
    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(entityLabel, c);
    c.gridx = 3;
    c.gridy = 0;
    c.gridwidth = 1;
    c.gridheight = 2;
    panel.add(entityTextField, c);

    JLabel hostLabel = new JLabel("Host name : ");
    final JTextField hostTextField = new JTextField(20);
    c.gridx = 0;
    c.gridy = 3;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(hostLabel, c);
    c.gridx = 3;
    c.gridy = 3;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(hostTextField, c);

    JLabel portLabel = new JLabel("Port number : ");
    final JTextField portTextField = new JTextField(10);
    c.gridx = 0;
    c.gridy = 5;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(portLabel, c);
    c.gridx = 3;
    c.gridy = 5;
    c.gridwidth = 1;
    c.gridheight = 2;
    panel.add(portTextField, c);

    final JButton connectButton = new JButton("Connect");
    connectButton.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {
        String stentity = entityTextField.getText();
        int entityid_ = new Integer(stentity).intValue();
        String hostname_ = hostTextField.getText();
        String portnr = portTextField.getText();
        int portnumber_ = new Integer(portnr).intValue();

        RobustPublisher(entityid_);
        Properties properties = createProperties(hostname_, portnr);
        try {
          initializeBrokerCommunications(properties, "niotcp");
          createButton.setEnabled(true);
          connectButton.setEnabled(false);
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }

        System.out.println("entity id :" + entityid_);
        System.out.println("host name : " + hostname_);
        System.out.println("port : " + portnumber_);

      }
    }

    );

    c.gridx = 2;
    c.gridy = 10;
    c.gridwidth = 4;
    c.gridheight = 2;

    panel.add(connectButton, c);

    return panel;
  }

  /**
   * Creates panel that consists radio buttons
   */
  protected JComponent makeRadioButtonPanel() {

    JRadioButton stringRadioButton, xmlRadioButton;
    JRadioButton integerRadioButton, regularExpRadioButton;
    JRadioButton tagValueExpRadioButton;
    ButtonGroup buttonGroup;
    JLabel templateTypeLabel;

    JPanel panel = new JPanel(false);
    panel.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    templateTypeLabel = new JLabel("Template Type :");

    stringRadioButton = new JRadioButton("String");
    stringRadioButton.setSelected(true);
    xmlRadioButton = new JRadioButton("XML");
    integerRadioButton = new JRadioButton("Integer      ");
    regularExpRadioButton = new JRadioButton("Regular Expression");
    tagValueExpRadioButton = new JRadioButton("Tag Value Pairs   ");

    buttonGroup = new ButtonGroup();
    buttonGroup.add(stringRadioButton);
    buttonGroup.add(xmlRadioButton);
    buttonGroup.add(integerRadioButton);
    buttonGroup.add(regularExpRadioButton);
    buttonGroup.add(tagValueExpRadioButton);

//Register a listener for the radio buttons.
    stringRadioButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        templateTextField.setText("11111");
        synopsisTextArea.setText("Movies/Casablanca");
        templateType_ = TemplateProfileAndSynopsisTypes.STRING;
      }
    }
    );

    String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
    xml += "\n<menu>\n <softdrinks>\n  <brand>Minute Maid</brand>";
    xml += "\n  <fruit>Apple</fruit>\n  <source>Brazil</source>";
    xml += "\n  <company>Coca Cola</company>\n  <price>2.90</price>";
    xml += "\n  <year>2004</year>\n </softdrinks>\n</menu>";
    final String xml_ = xml;

    xmlRadioButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        templateTextField.setText("22222");
        synopsisTextArea.setText(xml_);
        templateType_ = TemplateProfileAndSynopsisTypes.XML;
      }
    }
    );

    integerRadioButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        templateTextField.setText("33333");
        synopsisTextArea.setText("123456789");
        templateType_ = TemplateProfileAndSynopsisTypes.INTEGER;
      }
    }
    );

    regularExpRadioButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        templateTextField.setText("44444");
        synopsisTextArea.setText("The quick brown fox jumps upon the lazy dog");
        templateType_ = TemplateProfileAndSynopsisTypes.REGULAR_EXPRESSIONS;
      }
    }
    );

    tagValueExpRadioButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        templateTextField.setText("55555");
        synopsisTextArea.setText("Sport=NBA, Team=Bulls, Player=Jordan");
        templateType_ = TemplateProfileAndSynopsisTypes.TAG_VALUE_PAIRS;
      }
    }
    );
    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(templateTypeLabel, c);

    c.gridx = 1;
    c.gridy = 0;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(stringRadioButton, c);

    c.gridx = 2;
    c.gridy = 0;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(xmlRadioButton, c);

    c.gridx = 1;
    c.gridy = 1;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(integerRadioButton, c);

    c.gridx = 2;
    c.gridy = 1;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(regularExpRadioButton, c);

    c.gridx = 2;
    c.gridy = 2;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(tagValueExpRadioButton, c);

    return panel;
  }

  /**
   * creates Tabbed Tamplate info Pane
   */
  protected JComponent makeTemplatePanel() {

    JPanel panel = new JPanel(false);
    panel.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(makeRadioButtonPanel(), c);

    JLabel tamplateLabel = new JLabel("Template Id : ");
    templateTextField = new JTextField("11111", 20);
    c.gridx = 0;
    c.gridy = 2;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(tamplateLabel, c);
    c.gridx = 2;
    c.gridy = 2;
    c.gridwidth = 2;
    c.gridheight = 1;
    panel.add(templateTextField, c);

    JLabel synopsisLabel = new JLabel("Tamplate  : ");
    synopsisTextArea = new JTextArea("Movies/Casablanca", 3, 20);
    JScrollPane messageScroll = new JScrollPane(synopsisTextArea,
                                                JScrollPane.
                                                VERTICAL_SCROLLBAR_AS_NEEDED,
                                                JScrollPane.
                                                HORIZONTAL_SCROLLBAR_AS_NEEDED);

    c.gridx = 0;
    c.gridy = 3;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(synopsisLabel, c);
    c.gridx = 2;
    c.gridy = 3;
    c.gridwidth = 2;
    c.gridheight = 2;
    panel.add(messageScroll, c);

    createButton = new JButton("Create Producer");
    createButton.setEnabled(false);
    createButton.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {
        String sttemp = templateTextField.getText();
        int templid_ = new Integer(sttemp).intValue();
        teplateId = templid_;
        String tempsynopsis_ = synopsisTextArea.getText();
        synopsis_name = tempsynopsis_;
        try {
          initializeProducerAndConsumer(templid_, templateType_, tempsynopsis_);
          sendButton.setEnabled(true);
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }

      }
    }

    );

    c.gridx = 2;
    c.gridy = 5;
    c.gridwidth = 1;
    c.gridheight = 1;
    panel.add(createButton, c);

    return panel;
  }

  protected JComponent makeSendPanel() {

    JPanel panel = new JPanel(false);
    panel.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

    JLabel historyLabel = new JLabel("History : ");
    final JTextArea historyTextArea = new JTextArea(6, 25);
    historyTextArea.setLineWrap(true);
    historyTextArea.setEditable(false);
    JScrollPane historyScroll = new JScrollPane(historyTextArea,
                                                JScrollPane.
                                                VERTICAL_SCROLLBAR_AS_NEEDED,
                                                JScrollPane.
                                                HORIZONTAL_SCROLLBAR_AS_NEEDED);

    c.gridx = 0;
    c.gridy = 7;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(historyLabel, c);
    c.gridx = 3;
    c.gridy = 7;
    c.gridwidth = 1;
    c.gridheight = 2;
    panel.add(historyScroll, c);

    JLabel messageLabel = new JLabel("Message : ");
    final JTextArea messageTextArea = new JTextArea(4, 25);
    messageTextArea.setLineWrap(true);
    JScrollPane messageScroll = new JScrollPane(messageTextArea,
                                                JScrollPane.
                                                VERTICAL_SCROLLBAR_AS_NEEDED,
                                                JScrollPane.
                                                HORIZONTAL_SCROLLBAR_AS_NEEDED);

    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 3;
    c.gridheight = 2;
    panel.add(messageLabel, c);
    c.gridx = 3;
    c.gridy = 0;
    c.gridwidth = 1;
    c.gridheight = 2;
    panel.add(messageScroll, c);

    sendButton = new JButton("Send");
    sendButton.setEnabled(false);
    sendButton.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {
        String message = messageTextArea.getText();

        try {
          publishEvent(message, teplateId, synopsis_name);
          if (message.lastIndexOf("\n") < 0) {
            message = message + "\n";
          }
          historyTextArea.append("->" + message);
          messageTextArea.replaceRange("", 0, messageTextArea.getText().length());
        }
        catch (Exception ex) {
          ex.printStackTrace();
        }

      }
    }

    );

    c.gridx = 2;
    c.gridy = 5;
    c.gridwidth = 4;
    c.gridheight = 2;
    panel.add(sendButton, c);

    return panel;
  }

  /**
   * Create the GUI and show it.  For thread safety,
   * this method should be invoked from the
   * event-dispatching thread.
   */
  private static void createAndShowGUI() {
    //Make sure we have nice window decorations.
    JFrame.setDefaultLookAndFeelDecorated(true);

    //Create and set up the window.
    JFrame frame = new JFrame("Rebust Publisher");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Create and set up the content pane.
    JComponent newContentPane = new RobustPublisherGui();
    newContentPane.setOpaque(true); //content panes must be opaque
    frame.getContentPane().add(new RobustPublisherGui(),
                               BorderLayout.CENTER);

    //Display the window.
    //frame.pack();
    frame.setBounds(50, 50, 450, 300);
    frame.setVisible(true);
    frame.repaint();
  }

  private void jbInit() throws Exception {

  }

  public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });

  }
}
